home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / comm / tcp / rxsocket.lha / rxsocket / examples / troute.rexx < prev    next >
OS/2 REXX Batch file  |  2000-11-28  |  2KB  |  105 lines

  1. /* troute.rexx - a very stupid traceroute */
  2.  
  3. signal on break_c
  4.  
  5. l="rmh.library";if ~show("L",l) then;if ~addlib(l,0,-30) then exit
  6. prg=ProgramName("NOEXT")
  7. if AddLibrary("rexxsupport.library","rxsocket.library")~=0 then call err strings.ERRCANTFIND "'"result"'",1
  8.  
  9. if ~RMH_ReadArgs("HOST/A") then do
  10.     call PrintFault()
  11.     exit
  12. end
  13.  
  14. remote.addraddr=resolve(parm.0.value)
  15. if remote.addraddr=-1 then call err "host not found <"parm.0.value">",1
  16.  
  17. us=socket("INET","DGRAM")
  18. if us<0 then call err "can't create udp socket"
  19. is=socket("INET","RAW","ICMP")
  20. if us<0 then call error "can't create icmp socket"
  21.  
  22. secs=3
  23. tm=CreateTimer()
  24. ts=TimerSignal(tm)
  25.  
  26. uss=2**AllocSignal()
  27. call IOCtlSocket(us,"FIOASYNC",1)
  28. call SetSockOpt(us,"SOCKET","EVENTMASK","READ ERROR")
  29.  
  30. iss=2**AllocSignal()
  31. call IOCtlSocket(is,"FIOASYNC",1)
  32. call SetSockOpt(is,"SOCKET","EVENTMASK","READ ERROR")
  33.  
  34. call SetSocketBaseSingle("SIGEVENTMASK",or(uss,iss))
  35.  
  36. hope=3
  37. ttl=1
  38. baseport=30000
  39. mask=or(2**12,uss,iss,ts)
  40. stop=0
  41. do i=1 while ~stop
  42.  
  43.     remote.addrport=baseport
  44.     call SetSockOpt(us,"IP","TTL",ttl)
  45.     do hope=0 to 2
  46.         if sendto(us,"          ",0,"REMOTE")<0 then call err "error sendto"
  47.         srec=Wait(mask)
  48.         if and(srec,ts)==0 then do
  49.             if and(srec,2**12)>0 then call break_c
  50.             if and(srec,or(iss,uss))>0 then res=getEv()
  51.             do while res~=""
  52.                 say right(i,3) res
  53.                 hope=3
  54.                 if res==remote.addraddr then exit
  55.                 res=getEv()
  56.             end
  57.         end
  58.         else call writech(stdout,"* ")
  59.         call StartTimer(tm,3)
  60.     end
  61.     ttl=ttl+1
  62. end
  63. exit
  64.  
  65. err: procedure expose prg
  66. parse arg msg,ntdoerr
  67.     if ntdoerr~=1 then msg = msg "("ErrorString()")"
  68.     say prg":" msg
  69.     exit
  70.  
  71. break_c:
  72.     call err "interrputed",1
  73.  
  74. getEv:
  75.     s=GetSocketEvents("EV")
  76.     do while s>=0
  77.         if s=0 then call udpErr(ev.error,ev.read)
  78.         if ev.read then return parseICMP()
  79.         s=GetSocketEvents("EV")
  80.     end
  81.     return ""
  82.  
  83. udpErr: procedure
  84. parse arg e,r
  85.     if e then call err "error on udp"
  86.     else call err "port is listening, better change it",1
  87.  
  88. parseICMP:
  89.     if recvfrom(is,"BUF",256)<0 then call err "error receiving"
  90.     parse var buf iph +20 t +1 c +1 dummy +6 ipo +20
  91.     if  c2d(t)~=11 then
  92.         if  c2d(t)~=3 | c2d(c)~=3 then call err "bad icmp answer type:"c2d(t) "code:"c2d(c),1
  93.     call readIP(ipo,"IPH")
  94.     oid=iph.id
  95.     call readIP(iph,"IPH")
  96.     return iph.src
  97.  
  98.     call readICMP(BUF,"ICMP")
  99.     if icmp.type~=3 then return ""
  100.     if icmp.code~=3 then return ""
  101.     parse var buf addr +4
  102.     say c2x(buf)
  103.     return inetntoa(c2d(addr))
  104.  
  105.